package com.xbongbong.pro.message.service.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.message.domain.entity.PushLinkEntity;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.enums.DateEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.pojo.vo.IsActiveAIComboVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.PaasDateUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.message.enums.MessageGroupTypeEnum;
import com.xbongbong.pro.message.enums.MessageListSearchFilterMenuTagEnum;
import com.xbongbong.pro.message.enums.MessageListSearchFilterStatusTagEnum;
import com.xbongbong.pro.message.enums.MessageListSearchFilterTimeTagEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.feign.AIFeignClient;
import com.xbongbong.pro.message.model.PushLinkModel;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.pro.message.pojo.MessageGroupOutlinePojo;
import com.xbongbong.pro.message.pojo.MessagePojo;
import com.xbongbong.pro.message.pojo.MessageSearchFilterPojo;
import com.xbongbong.pro.message.pojo.MessageSearchMenuFilterPojo;
import com.xbongbong.pro.message.pojo.dto.MessageGroupDTO;
import com.xbongbong.pro.message.pojo.dto.MessageListDTO;
import com.xbongbong.pro.message.pojo.dto.MessageRemindListDTO;
import com.xbongbong.pro.message.pojo.dto.MessageSearchFilterDTO;
import com.xbongbong.pro.message.pojo.vo.MessageGroupVO;
import com.xbongbong.pro.message.pojo.vo.MessageSearchFilterVO;
import com.xbongbong.pro.message.pojo.vo.MessageVO;
import com.xbongbong.pro.message.service.MessageListService;
import com.xbongbong.pro.message.tool.PushTimeAscComparator;
import com.xbongbong.pro.message.tool.PushTimeDescComparator;
import com.xbongbong.pro.service.toolbox.smartsettings.help.SmartSettingsHelp;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.sys.model.FeeLogModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description: 消息列表相关
 * @author 李杰
 * @date 2019/1/9 10:59
 * @version v1.0
 * @since v1.0
 */
@Service("MessageListService")
public class MessageListServiceImpl implements MessageListService {

    private static final Logger LOG = LoggerFactory.getLogger(MessageListServiceImpl.class);
    @Resource
    private PushLinkModel pushLinkModel;
    @Resource
    private PushModel pushModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private SmartSettingsHelp smartSettingsHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private FeeLogModel feeLogModel;
    @Resource
    private AIFeignClient aiFeignClient;

    /**
     * Description: 获取消息分组list
     * @param messageGroupDTO 消息分组DTO
     * @return MessageGroupVO
     * @throws XbbException 数据库操作异常
     */
    @Override
    public MessageGroupVO groupList(MessageGroupDTO messageGroupDTO) throws XbbException {
        String platform = messageGroupDTO.getPlatform();
        MessageGroupVO messageGroupVO = new MessageGroupVO();
        List<MessageGroupOutlinePojo> groupOutlinePojoList = new ArrayList<>();
        List<MessageGroupTypeEnum> messageGroupTypeEnums = MessageGroupTypeEnum.getEnumByPlatform(platform);

        // 是否有智能助手菜单
        boolean hasAssistantMenu = smartSettingsHelp.hasMenu(messageGroupDTO.getCorpid());
        PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.DISTRIBUTOR.getAlias(), messageGroupDTO.getCorpid());
        boolean distributorEnable = false;
        if (Objects.nonNull(paasAppEntity) && Objects.equals(paasAppEntity.getEnable(), 1)) {
            distributorEnable = true;
        }

        // 套餐类型
        Integer feeType = packageHelp.getFeeType(messageGroupDTO.getCorpid());
        // 是否有数据中心菜单（数据中心的权限和图表中心的编辑权限,并且要要旗舰版）
        boolean hasDataCenterPerm = messageGroupDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.DATA_CENTER.getAlias())
                && Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Integer, List<PushEntity>> resultMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Integer, Integer> resultCountMap = new HashMap<>();
        params.put("corpid", messageGroupDTO.getCorpid());
        params.put("userId", messageGroupDTO.getUserId());
        params.put("del", 0);
        try {
            long time = DateTimeUtil.getInt();
            Boolean pastDue = feeLogModel.workOrderV2PastDue(messageGroupDTO.getCorpid());
            for (MessageGroupTypeEnum messageGroupTypeEnum : messageGroupTypeEnums) {
                if (Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.REMIND_MESSAGE)){
                    params.remove("refEntityIn");
                    params.remove("endPushTime");
                    getRemindList(messageGroupTypeEnum, resultMap, params, messageGroupDTO.getCorpid(), resultCountMap);
                    continue;
                }
                // 21132 Web后台首页消息浮层中不应展示SFA消息。
                if (Objects.equals(MessageGroupTypeEnum.AI_ASSISTANT, messageGroupTypeEnum) && !hasAssistantMenu) {
                    continue;
                }
                if (Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.DISTRIBUTOR_ORDER_CENTER)) {
                    continue;
                }
                // 工单关闭的话就没有消息
                if (Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.WORK_ORDER_V2) &&
                        (!paasAppModel.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getAlias(), SaasMarkEnum.SAAS.getCode(), messageGroupDTO.getCorpid()) || pastDue)) {
                    continue;
                }
                if (Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.DISTRIBUTOR_MARKETING_MANAGEMENT)) {
                    continue;
                }
                if ((Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.DISTRIBUTOR) || Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.MARKETING_MANAGEMENT)
                        || Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.ORDER_CENTER)) && !distributorEnable) {
                    continue;
                }
                if (Objects.equals(MessageGroupTypeEnum.DATA_CENTER, messageGroupTypeEnum) && !hasDataCenterPerm) {
                    continue;
                }
                //判断有无AI套餐，没有套餐，AI消息菜单隐藏
                if (Objects.equals(messageGroupTypeEnum, MessageGroupTypeEnum.AI_CENTER)){
                    IsActiveAIComboVO isActiveAIComboVO = isActiveAICombo(messageGroupDTO.getCorpid());
                    if (!isActiveAIComboVO.getIsExpired()){
                        continue;
                    }
                }
                List<Integer> refEntityList = new ArrayList<>();
                refEntityList.add(-1);
                refEntityList.addAll(MessageListSearchFilterMenuTagEnum.getRefEntityIdsById(messageGroupTypeEnum.getCode()));
                params.put("refEntityIn", refEntityList);
                params.put("isRemind", 0);
                params.put("isRead", 0);
                params.put("endPushTime", time);
                Integer count = pushLinkModel.getEntitysCount(params);
                resultCountMap.put(messageGroupTypeEnum.getCode(), count);
                getPushList(messageGroupTypeEnum, resultMap, messageGroupDTO.getCorpid(), messageGroupDTO.getUserId(), time);
            }

            //获取用户自定义应用，用于渲染消息列表的自定义icon和color,目前只处理了与原有saas应用
            params.clear();
            params.put(StringConstant.CORPID, messageGroupDTO.getCorpid());
            params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            List<PaasAppEntity> paasAppEntities = paasAppModel.findEntitys(params);
            Map<String, PaasAppEntity> paasAppEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasAppEntity entity : paasAppEntities) {
                paasAppEntityMap.put(entity.getAlias(), entity);
            }


            for (Map.Entry<Integer, List<PushEntity>> entry : resultMap.entrySet()) {
                Integer key = entry.getKey();
                MessageGroupTypeEnum messageGroupTypeEnum = MessageGroupTypeEnum.getEnumByCode(key);
                String title = messageGroupTypeEnum.getName();
                List<PushEntity> pushEntitys = entry.getValue();
                Integer count = resultCountMap.get(messageGroupTypeEnum.getCode());
                MessageGroupOutlinePojo messageGroupOutlinePojo = new MessageGroupOutlinePojo();
                messageGroupOutlinePojo.setAppId(key.longValue());
                messageGroupOutlinePojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                //默认icon和color
                if (Objects.equals(platform, PlatFormEnum.WEB.getValue())) {
                    messageGroupOutlinePojo.setIcon(messageGroupTypeEnum.getWebIcon());
                } else {
                    messageGroupOutlinePojo.setIcon(messageGroupTypeEnum.getAppIcon());
                }
                messageGroupOutlinePojo.setColor(messageGroupTypeEnum.getColor());
                //根据自定义渲染icon和color
                if (paasAppEntityMap.containsKey(messageGroupTypeEnum.getAlias())) {
                    PaasAppEntity entity = paasAppEntityMap.get(messageGroupTypeEnum.getAlias());
                    messageGroupOutlinePojo.setIcon(entity.getIcon());
                    messageGroupOutlinePojo.setColor(entity.getColor());
                }

                messageGroupOutlinePojo.setInfo(String.format(I18nMessageUtil.getMessage(I18nStringConstant.NEW_ARTICLE) + title, count));
                messageGroupOutlinePojo.setTitle(title);
                messageGroupOutlinePojo.setCount(count);
                if (messageGroupTypeEnum.equals(MessageGroupTypeEnum.REMIND_MESSAGE)) {
                    messageGroupOutlinePojo.setIsRemind(1);
                }
                if (pushEntitys.size() > 0) {
                    messageGroupOutlinePojo.setTime(pushEntitys.get(0).getPushTime());
                }
                groupOutlinePojoList.add(messageGroupOutlinePojo);
            }
            messageGroupVO.setGroupList(groupOutlinePojoList);
            //TODO message 未加入PaaS消息分组
        } catch (Exception e) {
            LOG.error("消息分组列表获取失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return messageGroupVO;
    }

    /**
     * Description: 获取具体消息list
     * @param messageListDTO 消息列表接口DTO
     * @return MessageVO
     * @throws XbbException 数据库操作异常
     */
    @Override
    public MessageVO list(MessageListDTO messageListDTO) throws XbbException {
        MessageVO messageVO = new MessageVO();
        List<MessagePojo> messagePojoList = new ArrayList<>();
        Integer saasMark = messageListDTO.getSaasMark();
        String corpid = messageListDTO.getCorpid();
        Integer isDownload = messageListDTO.getIsDownload();
        Integer isRead = messageListDTO.getStatusTags();
        Integer timeTag = messageListDTO.getTimeTags();
        Integer isRemind = messageListDTO.getIsRemind();
        List<Integer> refEntitys = messageListDTO.getRefEntity();
        List<Integer> typeList = messageListDTO.getType();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("userId", messageListDTO.getUserId());
        params.put("del", 0);
        params.put("page", messageListDTO.getPage());
        try {
            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                if (isRemind != null && isRemind.equals(1)) {
                    //跟进提醒
                    params.put("isRemind", isRemind);
                    params.put("startPushTime", DateUtil.getInt());
                    params.put("orderByStr", "push_time asc");
                } else if (isDownload != null && isDownload.equals(1)) {
                    //导入相关的消息，推的是下载链接
                    params.put("refEntityIn", Arrays.asList(PushTypeEnum.EXPORT_PUSH.getCode(), PushTypeEnum.EXPORT_PUSH_FAIL.getCode()));
                    params.put("orderByStr", "push_time desc");
                } else {
                    params.put("isRemind", 0);
                    if (refEntitys != null && refEntitys.size() > 0) {
                        params.put("refEntityIn", refEntitys);
                    } else {
                        refEntitys = MessageListSearchFilterMenuTagEnum.getRefEntityIdsById(messageListDTO.getAppId().intValue());
                        params.put("refEntityIn", refEntitys);
                    }
                    List<Object> betweenTime = new ArrayList<>();
                    if (Objects.equals(timeTag, MessageListSearchFilterTimeTagEnum.TODAY.getId())) {
                        betweenTime = PaasDateUtil.computeTime(Collections.singletonList(DateEnum.TODAY.getValue()));
                    } else if (Objects.equals(timeTag, MessageListSearchFilterTimeTagEnum.THIS_MONTH.getId())) {
                        betweenTime = PaasDateUtil.computeTime(Collections.singletonList(DateEnum.THIS_MONTH.getValue()));
                    } else if (Objects.equals(timeTag, MessageListSearchFilterTimeTagEnum.THIS_WEEK.getId())) {
                        betweenTime = PaasDateUtil.computeTime(Collections.singletonList(DateEnum.THIS_WEEK.getValue()));
                    }
                    if (betweenTime.size() > 0) {
                        params.put("startPushTime", betweenTime.get(0));
                        params.put("endPushTime", betweenTime.get(1));
                        if (Objects.equals(String.valueOf(messageListDTO.getAppId()),String.valueOf(MessageGroupTypeEnum.DATA_CENTER.getCode())) && Integer.parseInt(betweenTime.get(1).toString()) > DateTimeUtil.getInt()){
                            params.put("endPushTime",DateTimeUtil.getInt());
                        }
                    } else {
                        params.put("endPushTime", DateTimeUtil.getInt());
                    }
                    if (typeList != null && typeList.size() > 0) {
                        params.put("typeIn", typeList);
                    }
                    if (isRead != null) {
                        if (Objects.equals(isRead, MessageListSearchFilterStatusTagEnum.READ.getId())) {
                            params.put("isRead", 1);
                        } else if (Objects.equals(isRead, MessageListSearchFilterStatusTagEnum.UNREAD.getId())) {
                            params.put("isRead", 0);
                        }
                    }
                    // 普通消息
                    // 按是否已读正序排列，推送时间倒叙排列
                    String sortStr = "is_read ASC, push_time DESC";
                    params.put("orderByStr", sortStr);
                }
                PageHelper pageHelper = PageHelperUtil.getPageHelper(params, pushLinkModel, messageListDTO.getPageSize());
                List<PushLinkEntity> pushLinkList = (List<PushLinkEntity>) PageHelperUtil.getEntityList(params, pageHelper, pushLinkModel);

                List<PushEntity> pushList = formatPushList(pushLinkList, null, corpid, messageListDTO.getIsRemind());
                for (PushEntity pushEntity : pushList) {
                    MessagePojo messagePojo = new MessagePojo();
                    BeanUtil.copyProperties(pushEntity, messagePojo, true);
                    messagePojo.setId(pushEntity.getId());
                    messagePojo.setMsg(JSON.parseObject(pushEntity.getMsg()));
                    messagePojo.setRefType(JSON.parseObject(pushEntity.getRefType()));
                    messagePojo.setPushLinkId(pushEntity.getPushLinkId());
                    messagePojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    messagePojoList.add(messagePojo);
                }
                messageVO.setList(messagePojoList);
                messageVO.setCount(pageHelper.getRowsCount());
            } else {
                // TODO  PaaS
            }
        } catch (Exception e) {
            LOG.error("消息列表获取失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return messageVO;
    }

    /**
     * Description: 获取具体消息筛选项
     * @param messageSearchFilterDTO 消息列表筛选DTO
     * @return MessageSearchFilterVO
     * @throws XbbException 参数异常
     */
    @Override
    public MessageSearchFilterVO searchFilter(MessageSearchFilterDTO messageSearchFilterDTO) throws XbbException {
        MessageSearchFilterVO messageSearchFilterVO = new MessageSearchFilterVO();
        try {
            String corpid = messageSearchFilterDTO.getCorpid();
            if (Objects.equals(messageSearchFilterDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                //saas
                List<MessageListSearchFilterMenuTagEnum> menuTagEnums;
                if (messageSearchFilterDTO.getAppId().equals(MessageListSearchFilterMenuTagEnum.WORK_ORDER.getId().longValue()) ||
                        messageSearchFilterDTO.getAppId().equals(MessageListSearchFilterMenuTagEnum.WORK_ORDER_V2.getId().longValue())) {
                    menuTagEnums = new ArrayList<>();
                } else if (messageSearchFilterDTO.getAppId().equals(MessageListSearchFilterMenuTagEnum.DATA_CENTER.getId().longValue())) {
                    menuTagEnums = new ArrayList<>();
                } else {
                    menuTagEnums = MessageListSearchFilterMenuTagEnum.getEnumsById(messageSearchFilterDTO.getAppId().intValue());
                }
                List<MessageListSearchFilterTimeTagEnum> timeTagEnums = MessageListSearchFilterTimeTagEnum.getAllEnum();
                List<MessageListSearchFilterStatusTagEnum> statusTagEnums = MessageListSearchFilterStatusTagEnum.getAllEnum();
                List<MessageSearchMenuFilterPojo> menuTags = new ArrayList<>();
                List<MessageSearchFilterPojo> timeTags = new ArrayList<>();
                List<MessageSearchFilterPojo> statusTags = new ArrayList<>();
                boolean openWorkflow = commonHelp.isOpenWorkFlow(corpid);
                boolean customerSeniorModel = commonHelp.isCustomerPublicPoolSeniorModel(corpid);
                boolean clueSeniorModel = commonHelp.isCluePublicPoolSeniorModel(corpid);
                for (MessageListSearchFilterMenuTagEnum tagEnum : menuTagEnums) {
                    MessageSearchMenuFilterPojo pojo = new MessageSearchMenuFilterPojo();
                    if (!openWorkflow && Objects.equals(MessageListSearchFilterMenuTagEnum.WORKFLOW_MESSAGE, tagEnum)) {
                        continue;
                    }
                    if (!customerSeniorModel && Objects.equals(MessageListSearchFilterMenuTagEnum.CUSTOMER_TRANSFER_REMIND,tagEnum)){
                        continue;
                    }
                    if (!clueSeniorModel && Objects.equals(MessageListSearchFilterMenuTagEnum.CLUE_TRANSFER_REMIND,tagEnum)){
                        continue;
                    }
                    pojo.setId(tagEnum.getId());
                    pojo.setRefEntity(tagEnum.getRefEntity());
                    pojo.setType(tagEnum.getType());
                    pojo.setValue(tagEnum.getName());
                    menuTags.add(pojo);
                }
                for (MessageListSearchFilterTimeTagEnum tagEnum : timeTagEnums) {
                    MessageSearchFilterPojo pojo = new MessageSearchFilterPojo();
                    pojo.setId(tagEnum.getId());
                    pojo.setValue(tagEnum.getName());
                    timeTags.add(pojo);
                }
                for (MessageListSearchFilterStatusTagEnum tagEnum : statusTagEnums) {
                    MessageSearchFilterPojo pojo = new MessageSearchFilterPojo();
                    pojo.setId(tagEnum.getId());
                    pojo.setValue(tagEnum.getName());
                    statusTags.add(pojo);
                }

                messageSearchFilterVO.setMenuTags(menuTags);
                messageSearchFilterVO.setTimeTags(timeTags);
                messageSearchFilterVO.setStatusTags(statusTags);
            } else if (Objects.equals(messageSearchFilterDTO.getSaasMark(), SaasMarkEnum.PAAS.getCode())) {
                //paas

            } else {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, SystemErrorCodeEnum.API_ERROR_100028.getMsg());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("消息筛选初始化失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return messageSearchFilterVO;
    }

    /**
     * Description: 移动端首页 消息列表
     * @param messageListDTO messageListDTO
     * @return MessageVO
     * @throws XbbException  XbbException
     */
    @Override
    public MessageVO indexList(MessageListDTO messageListDTO) throws XbbException {
        MessageVO messageVO = new MessageVO();
        List<MessagePojo> messagePojos = new ArrayList<>();
        Integer saasMark = messageListDTO.getSaasMark();
        String corpid = messageListDTO.getCorpid();
        String userId = messageListDTO.getUserId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("userId", userId);
        params.put("del", 0);
        params.put("page", messageListDTO.getPage());
        try {
            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                params.put("isRemind", 0);
                // 按是否已读正序排列，推送时间倒叙排列
                String sortStr = "is_read ASC, push_time DESC";
                params.put("orderByStr", sortStr);
                PageHelper pageHelper = PageHelperUtil.getPageHelper(params, pushLinkModel, messageListDTO.getPageSize());
                List<PushLinkEntity> pushLinkList = (List<PushLinkEntity>) PageHelperUtil.getEntityList(params, pageHelper, pushLinkModel);
                List<PushEntity> pushList = formatPushList(pushLinkList, null, corpid, 0);
                for (PushEntity entity : pushList) {
                    MessagePojo messagePojo = new MessagePojo();
                    BeanUtil.copyProperties(entity, messagePojo, true);
                    messagePojo.setId(entity.getId());
                    messagePojo.setMsg(JSON.parseObject(entity.getMsg()));
                    messagePojo.setPushLinkId(entity.getPushLinkId());
                    messagePojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    messagePojos.add(messagePojo);
                }
                messageVO.setList(messagePojos);
                messageVO.setCount(pageHelper.getRowsCount());
            } else if (Objects.equals(saasMark, SaasMarkEnum.PAAS.getCode())) {
                // TODO  PaaS
            }
        } catch (Exception e) {
            LOG.error("移动端消息列表获取失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return messageVO;
    }

    @Override
    public MessageVO indexRemindList(MessageRemindListDTO messageRemindListDTO) throws XbbException {
        MessageVO messageVO = new MessageVO();

        List<MessagePojo> messagePojoList = new ArrayList<>();
        String corpid = messageRemindListDTO.getCorpid();
        Integer isRemind = 1;
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("userId", messageRemindListDTO.getUserId());
        params.put("del", DelEnum.NORMAL.getDel());
        params.put("page", 1);
        params.put("isRemind", isRemind);
        params.put("startPushTime", DateUtil.getInt());
        params.put("isRead", 0);
        String sortStr = "is_read ASC, push_time DESC";
        params.put("orderByStr", sortStr);
        try {
            // 首页看板：获取2条跟进提醒
            PageHelper pageHelper = PageHelperUtil.getPageHelper(params, pushLinkModel, 3);
            List<PushLinkEntity> pushLinkList = (List<PushLinkEntity>) PageHelperUtil.getEntityList(params, pageHelper, pushLinkModel);

            List<PushEntity> pushList = formatPushList(pushLinkList, null, corpid, isRemind);
            for (PushEntity pushEntity : pushList) {
                MessagePojo messagePojo = new MessagePojo();
                BeanUtil.copyProperties(pushEntity, messagePojo, true);
                messagePojo.setId(pushEntity.getId());
                messagePojo.setMsg(JSON.parseObject(pushEntity.getMsg()));
                messagePojo.setPushLinkId(pushEntity.getPushLinkId());
                messagePojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                messagePojoList.add(messagePojo);
            }
            messageVO.setList(messagePojoList);
            messageVO.setCount(pageHelper.getRowsCount());

        } catch (Exception e) {
            LOG.error("跟进提醒列表获取失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return messageVO;
    }

    @Override
    public PushEntity indexSalesReport(String corpid, String userId) {

        Integer isRemind = 0;
        List<Integer> refEntitys = MessageListSearchFilterMenuTagEnum.SALE_REPORT.getRefEntity();
        List<Integer> typeList = MessageListSearchFilterMenuTagEnum.SALE_REPORT.getType();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("userId", userId);
        params.put("del", DelEnum.NORMAL.getDel());
        params.put("page", 1);
        params.put("isRemind", isRemind);
        params.put("refEntityIn", refEntitys);
        params.put("typeIn", typeList);
        params.put("isRead", 0);
        String sortStr = "is_read ASC, push_time DESC";
        params.put("orderByStr", sortStr);

        PageHelper pageHelper = PageHelperUtil.getPageHelper(params, pushLinkModel, 1);
        try {
            List<PushLinkEntity> pushLinkList = (List<PushLinkEntity>) PageHelperUtil.getEntityList(params, pageHelper, pushLinkModel);
            List<PushEntity> pushList = formatPushList(pushLinkList, null, corpid, isRemind);
            if(pushList.size() > 0) {
                return pushList.get(0);
            }
        } catch (Exception e) {
            LOG.error("消息列表获取失败", e);
        }
        return null;
    }

    /**
     * Description: 根据pushLink返回消息具体
     * @param messageGroupTypeEnum 消息分组枚举
     * @param map 结果存储map
     * @param corpid 公司id
     * @param userId
     * @param time
     */
    private void getPushList(MessageGroupTypeEnum messageGroupTypeEnum, Map<Integer, List<PushEntity>> map, String corpid, String userId, long time) {
        Map<String, Object> params = new HashMap<>();
        params.put("corpid", corpid);
        params.put("userId", userId);
        params.put("del", 0);
        List<Integer> refEntityList = new ArrayList<>();
        refEntityList.add(-1);
        refEntityList.addAll(MessageListSearchFilterMenuTagEnum.getRefEntityIdsById(messageGroupTypeEnum.getCode()));
        params.put("refEntityIn", refEntityList);
        params.put("isRemind", 0);
        params.put("isRead", 0);
        params.put("orderByStr", "push_time DESC");
        params.put("limitNum", 1);
        params.put("endPushTime", time);
        List<PushLinkEntity> pushLinkList = pushLinkModel.findEntitys(params);

        if (pushLinkList == null || pushLinkList.size() == 0) {
            map.put(messageGroupTypeEnum.getCode(), new ArrayList<>());
            return;
        }
        List<Long> pushIdInList = new ArrayList<>();
        for (PushLinkEntity pushLink : pushLinkList) {
            pushIdInList.add(pushLink.getPushId());
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("pushIdIn", pushIdInList);
        param.put("corpid", corpid);
        param.put("orderByStr", "push_time DESC");
        List<PushEntity> pushList = pushModel.findEntitys(param);
        map.put(messageGroupTypeEnum.getCode(), pushList);
    }

    /**
     * 根据推送信息关联表获取推送信息表并封装信息
     * @param pushLinkList 消息关联列表
     * @param refId        对象Id
     * @param isRemind     是否为跟进提醒消息：0 普通消息；1 跟进提醒
     * @return 消息队列
     */
    @Override
    public List<PushEntity> formatPushList(List<PushLinkEntity> pushLinkList, Integer refId, String corpid, Integer isRemind) throws XbbException {

        if (pushLinkList == null || pushLinkList.size() == 0) {
            return new ArrayList<>();
        }
        List<Long> pushIdInList = new ArrayList<>();
        for (PushLinkEntity pushLink : pushLinkList) {
            pushIdInList.add(pushLink.getPushId());
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("pushIdIn", pushIdInList);
        param.put("corpid", corpid);
        List<PushEntity> pushList = pushModel.findEntitys(param);
        List<PushEntity> unReadPushList = new ArrayList<>();
        List<PushEntity> unPushPushList = new ArrayList<>();
        List<PushEntity> readPushList = new ArrayList<>();
        for (PushEntity push : pushList) {
/*            Integer refEntity = push.getRefEntity();
            //销售简报推送，处理一下start和end
            if (refEntity.equals(XbbRefTypeEnum.SALES_REPORT_ENTITY.getCode())) {
                JSONObject messageObject = null;
                try {
                    messageObject = JSONObject.parseObject(push.getMsg());
                } catch (Exception e) {
                    LOG.error("类型转换错误", e);
                }
                if (messageObject != null) {
                    Integer dayStartTime = messageObject.getInteger("start");
                    Integer dayEndTime = messageObject.getInteger("end");
                    push.setStart(dayStartTime);
                    push.setEnd(dayEndTime);
                }
            }*/
            // 补全消息的 msg 部分的 content
            // TODO: 2019/4/2 下面备注的东西弃用，以及相关的东西都弃用，消息格式改了
//            push.setMsg(MessageFormat.formatMessageContent(push.getMsg()));
            for (int i = (pushLinkList.size() - 1); i > -1; i--) {
                if (Objects.equals(push.getId(), pushLinkList.get(i).getPushId())) {
                    if (refId != null && !Objects.equals(refId, push.getRefId())) {
                        continue;
                    }
                    PushLinkEntity pushLink = pushLinkList.get(i);
                    push.setPushLinkId(pushLink.getId());
                    push.setIsRead(pushLink.getIsRead());
                    if (push.getIsRead() == 0) {
                        // 未读消息
                        if (push.getIsPush() == 0) {
                            // 即将提醒（未发送）
                            unPushPushList.add(push);
                        } else {
                            // 已发送消息（未读）
                            unReadPushList.add(push);
                        }
                    } else {
                        if (push.getIsPush() == 0) {
                            // 即将提醒（未发送） 脏数据
                            pushLink.setIsRead(1);
                            pushLinkModel.update(pushLink);

                            push.setIsRead(1);
                            unPushPushList.add(push);
                        } else {
                            // 已发送消息（未读）未读
                            readPushList.add(push);
                        }
                    }
                    pushLinkList.remove(i);
                    break;
                }
            }
        }
        if (isRemind != null && isRemind == 1) {
            // 未发送的提醒升序排列
            unPushPushList.sort(new PushTimeAscComparator());
        } else {
            // 未发送的消息降序排列
            unPushPushList.sort(new PushTimeDescComparator());
        }
        // 未读消息降序排列
        unReadPushList.sort(new PushTimeDescComparator());
        // 已读消息降序排列
        readPushList.sort(new PushTimeDescComparator());
        pushList.clear();
        pushList.addAll(unReadPushList);
        pushList.addAll(unPushPushList);
        pushList.addAll(readPushList);
        return pushList;
    }

    /**
     * Description: 获取未推送提醒消息（app）
     * @param messageGroupTypeEnum 消息分组枚举
     * @param map 结果存储map
     * @param params 查询参数
     * @param corpid 公司id
     * @param countMap 计数统计
     */
    private void getRemindList(MessageGroupTypeEnum messageGroupTypeEnum, Map<Integer, List<PushEntity>> map, Map<String, Object> params, String corpid, Map<Integer, Integer> countMap) {
        params.put("isRemind", 1);
        params.put("isRead", 0);
        params.put("startPushTime", DateTimeUtil.getInt());
        Integer count = pushLinkModel.getEntitysCount(params);
        countMap.put(messageGroupTypeEnum.getCode(), count);

        params.put("limitNum", 1);
        params.put("orderByStr", "push_time DESC");
        List<PushLinkEntity> pushLinkList = pushLinkModel.findEntitys(params);
        params.remove("limitNum");
        params.remove("orderByStr");
        List<Long> pushIdInList = new ArrayList<>();
        pushIdInList.add(-1L);
        for (PushLinkEntity pushLink : pushLinkList) {
            pushIdInList.add(pushLink.getPushId());
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("pushIdIn", pushIdInList);
        param.put("corpid", corpid);
        param.put("orderByStr", "push_time ASC");
        List<PushEntity> pushList = pushModel.findEntitys(param);
        map.put(messageGroupTypeEnum.getCode(), pushList);
    }

    /**
     * 判断有无开启AI套餐
     */
    private IsActiveAIComboVO isActiveAICombo(String corpid)throws XbbException{
        //判断是否开启套餐
        IsActiveAIComboVO vo = new IsActiveAIComboVO();
        vo.setIsExpired(false);
        XbbResponse<IsActiveAIComboVO> response = new XbbResponse<>(vo);
        try {
            BaseDTO baseDTO = new BaseDTO();
            baseDTO.setCorpid(corpid);
            baseDTO.setUserId("0");
            baseDTO.setPlatform("web");
            String lang = LocaleContextHolder.getLocale().toString();
            response = aiFeignClient.isActiveCombo(baseDTO, lang);
            if (!Objects.equals(response.getCode(), ErrorCodeEnum.API_SUCCESS.getCode())) {
                return vo;
            }
        }catch (Exception e){
            LOG.info("corpid为{}未开启AI",corpid);
        }
        return response.getResult();
    }
}
